import Taro from '@tarojs/taro'

// 环境配置
const isDev = process.env.NODE_ENV === 'development' || process.env.TARO_ENV === 'weapp';

// 请求基础URL
const BASE_URL = isDev ? 'http://localhost:5125' : 'https://your-api-domain.com';

// 请求拦截器参数
interface RequestParams {
  url: string
  data?: any
  method?: 'GET' | 'POST' | 'PUT' | 'DELETE'
  header?: Record<string, string>
  [key: string]: any
}

// 响应数据接口 - 匹配后端API格式（camelCase）
interface ResponseData<T = any> {
  code: number
  data: T
  message: string
  isSuccess: boolean
  timestamp: number
}

// 分页响应数据接口
export interface PagedResponseData<T = any> extends ResponseData<T[]> {
  total: number
  page: number
  pageSize: number
  totalPages: number
}

/**
 * 请求拦截器
 * @param params 请求参数
 */
const requestInterceptor = (params: RequestParams): RequestParams => {
  // 添加token到请求头
  const token = Taro.getStorageSync('token')
  if (token) {
    params.header = {
      ...params.header,
      'Authorization': `Bearer ${token}`
    }
  }
  
  // 补全请求URL
  if (!params.url.startsWith('http')) {
    params.url = `${BASE_URL}${params.url}`
  }
  
  // 添加默认header
  params.header = {
    'Content-Type': 'application/json',
    ...params.header
  }
  
  return params
}

/**
 * 响应拦截器
 * @param response 响应数据
 */
const responseInterceptor = <T>(response: any): ResponseData<T> => {
  // 统一处理响应数据
  if (response.statusCode === 200) {
    const { data } = response
    
    // 如果接口返回错误码，统一处理
    if (data.code !== 0 && data.code !== 200) {
      Taro.showToast({
        title: data.message || '请求失败',
        icon: 'none',
        duration: 2000
      })
      
      // 处理登录失效
      if (data.code === 401) {
        Taro.clearStorageSync()
        Taro.navigateTo({
          url: '/pages/login/index'
        })
      }
      
      throw new Error(data.message || '请求失败')
    }
    
    return data
  }
  
  // 处理HTTP错误
  Taro.showToast({
    title: `请求失败: ${response.statusCode}`,
    icon: 'none',
    duration: 2000
  })
  
  throw new Error(`网络请求错误: ${response.statusCode}`)
}

/**
 * 网络请求
 * @param options 请求选项
 */
const request = <T = any>(options: RequestParams): Promise<ResponseData<T>> => {
  const interceptedOptions = requestInterceptor(options)
  
  return new Promise((resolve, reject) => {
    Taro.request({
      ...interceptedOptions,
      success: (res) => {
        try {
          const response = responseInterceptor<T>(res)
          resolve(response)
        } catch (error) {
          reject(error)
        }
      },
      fail: (err) => {
        Taro.showToast({
          title: '网络连接失败',
          icon: 'none',
          duration: 2000
        })
        reject(err)
      }
    })
  })
}

/**
 * GET请求
 * @param url 请求URL
 * @param data 请求参数
 * @param header 请求头
 */
export const get = <T = any>(url: string, data?: any, header?: Record<string, string>): Promise<ResponseData<T>> => {
  return request<T>({
    url,
    data,
    method: 'GET',
    header
  })
}

/**
 * POST请求
 * @param url 请求URL
 * @param data 请求参数
 * @param header 请求头
 */
export const post = <T = any>(url: string, data?: any, header?: Record<string, string>): Promise<ResponseData<T>> => {
  return request<T>({
    url,
    data,
    method: 'POST',
    header
  })
}

/**
 * PUT请求
 * @param url 请求URL
 * @param data 请求参数
 * @param header 请求头
 */
export const put = <T = any>(url: string, data?: any, header?: Record<string, string>): Promise<ResponseData<T>> => {
  return request<T>({
    url,
    data,
    method: 'PUT',
    header
  })
}

/**
 * DELETE请求
 * @param url 请求URL
 * @param data 请求参数
 * @param header 请求头
 */
export const del = <T = any>(url: string, data?: any, header?: Record<string, string>): Promise<ResponseData<T>> => {
  return request<T>({
    url,
    data,
    method: 'DELETE',
    header
  })
}

export default {
  get,
  post,
  put,
  del
} 